﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.UI.WebControls;
using DomainModel;
using Services.Abstract;

namespace Web
{
    public partial class Semesters : BasePage
    {
        public IStudyYearService StudyYearService { get; set; }
        public ISemesterService SemesterService { get; set; }
        public IPermissionService PermissionService { get; set; }

        protected StudyYear CurrentStudyYear;

        protected new void Page_Load(object sender, EventArgs e)
        {
            SelectMenuItem("NavSemesters");

            InitAdditionalControls();

            BindListViewStudyYears();

            if (Request.QueryString["StudyYearId"] != null)
            {
                try
                {
                    long studyYearId = long.Parse(Request.QueryString["StudyYearId"]);
                    CurrentStudyYear = StudyYearService.GetById(studyYearId);
                    SemestersSection.Visible = true;
                    BindListViewSemesters();
                }
                catch (Exception)
                {
                    Response.Redirect("/Semesters.aspx");
                }
            }
        }

        private void BindListViewStudyYears()
        {
            var studyYearsList = StudyYearService.GetAll().OrderBy(y => y.BeginDate).ToList();

            var ds = new List<object>();

            foreach (var studyYear in studyYearsList)
            {
                ds.Add(new
                           {
                               Id = studyYear.Id,
                               Name = studyYear.Name,
                               BeginDate = studyYear.BeginDate.ToShortDateString(),
                               EndDate = studyYear.EndDate.ToShortDateString(),
                           });
            }

            ListViewStudyYears.DataSource = ds;
            ListViewStudyYears.DataBind();
        }

        private void ShowEditStudyYearForm(long id = 0, string beginDate = null, string endDate = null, bool showDeleteBtn = false)
        {
            if (id != 0)
            {
                if (ViewState["studyYearId"] == null)
                {
                    ViewState.Add("studyYearId", id);
                }
                else
                {
                    ViewState["studyYearId"] = id;
                }
            }
            else
            {
                if (ViewState["studyYearId"] != null)
                {
                    ViewState.Remove("studyYearId");
                }
            }

            TbStudyYearBeginDate.Text = beginDate ?? "";
            TbStudyYearEndDate.Text = endDate ?? "";

            ButtonDeleteStudyYear.Visible = showDeleteBtn;

            EditStudyYearForm.Visible = true;
        }

        private void HideEditStudyYearForm()
        {
            if (ViewState["studyYearId"] != null)
            {
                ViewState.Remove("studyYearId");
            }

            EditStudyYearForm.Visible = false;
        }

        protected void BtnAddStudyYear_OnClick(object sender, EventArgs e)
        {
            ShowEditStudyYearForm();
        }

        protected void BtnChangeStudyYear_OnClick(object sender, EventArgs e)
        {
            long studyYearId;
            try
            {
                var listView = ((LinkButton)sender).Parent as ListViewDataItem;
                var dataKey = ListViewStudyYears.DataKeys[listView.DataItemIndex];
                studyYearId = long.Parse(dataKey.Value.ToString());
            }
            catch (Exception)
            {
                ShowSysMsg("Возникла непредвиденная ошибка.");
                return;
            }

            var studyYear = StudyYearService.GetById(studyYearId);
            if (studyYear == null)
            {
                ShowSysMsg("Ошибка базы данных. Невозможно найти учебный год.");
                return;
            }

            ShowEditStudyYearForm(studyYearId, studyYear.BeginDate.ToShortDateString(), studyYear.EndDate.ToShortDateString(), true);
        }

        protected void ButtonSaveStudyYear_OnClick(object sender, EventArgs e)
        {
            DateTime beginDate;
            DateTime endDate;

            try
            {
                beginDate = DateTime.Parse(TbStudyYearBeginDate.Text);
            }
            catch (FormatException)
            {
                ShowFormError(EditStudyYearFormError.ClientID, "Дата начала введена в неверном формате.");
                return;
            }
            catch (Exception)
            {
                ShowSysMsg("Возникла непредвиденная ошибка.");
                return;
            }

            try
            {
                endDate = DateTime.Parse(TbStudyYearEndDate.Text);
            }
            catch (FormatException)
            {
                ShowFormError(EditStudyYearFormError.ClientID, "Дата конца введена в неверном формате.");
                return;
            }
            catch (Exception)
            {
                ShowSysMsg("Возникла непредвиденная ошибка.");
                return;
            }

            StudyYear studyYear;
            if (ViewState["studyYearId"] == null)
            {
                studyYear = new StudyYear(beginDate, endDate);
            }
            else
            {
                long studyYearId;
                try
                {
                    studyYearId = long.Parse(ViewState["studyYearId"].ToString());
                }
                catch (Exception)
                {
                    ShowSysMsg("Возникла непредвиденная ошибка.");
                    return;
                }

                studyYear = StudyYearService.GetById(studyYearId);
                if (studyYear == null)
                {
                    ShowSysMsg("Ошибка базы данных. Невозможно найти учеьный год.");
                    return;
                }

                studyYear.BeginDate = beginDate;
                studyYear.EndDate = endDate;
            }

            try
            {
                StudyYearService.SaveOrUpdate(studyYear);

                HideEditStudyYearForm();
                BindListViewStudyYears();
            }
            catch (Exception ex)
            {
                ShowFormError(EditStudyYearFormError.ClientID, ex.Message);
            }
        }

        protected void ButtonDeleteStudyYear_OnClick(object sender, EventArgs e)
        {
            if (ViewState["studyYearId"] == null)
            {
                return;
            }

            long studyYearId;
            try
            {
                studyYearId = long.Parse(ViewState["studyYearId"].ToString());
            }
            catch (Exception)
            {
                ShowSysMsg("Возникла непредвиденная ошибка.");
                return;
            }

            var studyYear = StudyYearService.GetById(studyYearId);
            if (studyYear == null)
            {
                ShowSysMsg("Ошибка базы данных. Невозможно найти учеьный год.");
                return;
            }

            try
            {
                StudyYearService.Delete(studyYear);

                HideEditStudyYearForm();
                HideSemestersSection();

                BindListViewStudyYears();
            }
            catch (Exception ex)
            {
                ShowFormError(EditStudyYearFormError.ClientID, ex.Message);
            }
        }

        private void HideSemestersSection()
        {
            SemestersSection.Visible = false;
        }

        protected void ButtonCancelStudyYear_OnClick(object sender, EventArgs e)
        {
            HideEditStudyYearForm();
        }

        private void BindListViewSemesters()
        {
            var semestersList = SemesterService.GetSemestersByStudyYear(CurrentStudyYear).OrderBy(s => s.BeginDate);

            var ds = new List<object>();

            int semesterNumber = 1;
            foreach (var semester in semestersList)
            {
                ds.Add(new
                {
                    Id = semester.Id,
                    StudyYearName = semester.StudyYear.Name,
                    SemesterNumber = semesterNumber++,
                    BeginDate = semester.BeginDate.ToShortDateString(),
                    EndDate = semester.EndDate.ToShortDateString(),
                });
            }

            ListViewSemesters.DataSource = ds;
            ListViewSemesters.DataBind();
        }

        private void ShowEditSemesterForm(long id = 0, string beginDate = null, string endDate = null, bool showDeleteBtn = false)
        {
            if (id != 0)
            {
                if (ViewState["semesterId"] == null)
                {
                    ViewState.Add("semesterId", id);
                }
                else
                {
                    ViewState["semesterId"] = id;
                }
            }
            else
            {
                if (ViewState["semesterId"] != null)
                {
                    ViewState.Remove("semesterId");
                }
            }

            TbSemesterBeginDate.Text = beginDate ?? "";
            TbSemesterEndDate.Text = endDate ?? "";

            ButtonDeleteSemester.Visible = showDeleteBtn;

            EditSemesterForm.Visible = true;
        }

        private void HideEditSemesterForm()
        {
            if (ViewState["semesterId"] != null)
            {
                ViewState.Remove("semesterId");
            }

            EditSemesterForm.Visible = false;
        }

        protected void BtnAddSemester_OnClick(object sender, EventArgs e)
        {
            ShowEditSemesterForm();
        }

        protected void BtnChangeSemester_OnClick(object sender, EventArgs e)
        {
            long semesterId;
            try
            {
                var listView = ((LinkButton)sender).Parent as ListViewDataItem;
                var dataKey = ListViewSemesters.DataKeys[listView.DataItemIndex];
                semesterId = long.Parse(dataKey.Value.ToString());
            }
            catch (Exception)
            {
                ShowSysMsg("Возникла непредвиденная ошибка.");
                return;
            }

            var semester = SemesterService.GetById(semesterId);
            if (semester == null)
            {
                ShowSysMsg("Ошибка базы данных. Невозможно найти семестр.");
                return;
            }

            if (ViewState["semesterId "] == null)
            {
                ViewState.Add("semesterId ", semesterId);
            }
            else
            {
                ViewState["semesterId "] = semesterId;
            }

            ShowEditSemesterForm(semesterId, semester.BeginDate.ToShortDateString(), semester.EndDate.ToShortDateString(), true);
        }

        protected void ButtonSaveSemester_OnClick(object sender, EventArgs e)
        {
            DateTime beginDate;
            DateTime endDate;

            try
            {
                beginDate = DateTime.Parse(TbSemesterBeginDate.Text);
            }
            catch (FormatException)
            {
                ShowFormError(EditStudyYearFormError.ClientID, "Дата начала введена в неверном формате.");
                return;
            }
            catch (Exception)
            {
                ShowSysMsg("Ошибка базы данных. Невозможно найти семестр.");
                return;
            }

            try
            {
                endDate = DateTime.Parse(TbSemesterEndDate.Text);
            }
            catch (FormatException)
            {
                ShowFormError(EditStudyYearFormError.ClientID, "Дата конца введена в неверном формате.");
                return;
            }
            catch (Exception)
            {
                ShowSysMsg("Ошибка базы данных. Невозможно найти семестр.");
                return;
            }

            StudySemester semester;
            if (ViewState["semesterId"] == null)
            {
                semester = new StudySemester(CurrentStudyYear, beginDate, endDate);
            }
            else
            {
                long studyYearId;
                try
                {
                    studyYearId = long.Parse(ViewState["semesterId"].ToString());
                }
                catch (Exception)
                {
                    ShowSysMsg("Возникла непредвиденная ошибка.");
                    return;
                }

                semester = SemesterService.GetById(studyYearId);

                if (semester == null)
                {
                    ShowSysMsg("Ошибка базы данных. Невозможно найти учеьный год.");
                    return;
                }

                semester.BeginDate = beginDate;
                semester.EndDate = endDate;
            }

            try
            {
                SemesterService.SaveOrUpdate(semester);

                HideEditSemesterForm();
                BindListViewSemesters();
            }
            catch (Exception ex)
            {
                ShowFormError(EditSemesterFormError.ClientID, ex.Message);
            }
        }

        protected void ButtonDeleteSemester_OnClick(object sender, EventArgs e)
        {
            if (ViewState["semesterId"] == null)
            {
                return;
            }

            long studyYearId;
            try
            {
                studyYearId = long.Parse(ViewState["semesterId"].ToString());
            }
            catch (Exception)
            {
                ShowSysMsg("Возникла непредвиденная ошибка.");
                return;
            }

            StudySemester semester = SemesterService.GetById(studyYearId);

            if (semester == null)
            {
                ShowSysMsg("Ошибка базы данных. Невозможно найти учеьный год.");
                return;
            }

            try
            {
                SemesterService.Delete(semester);

                HideEditSemesterForm();
                BindListViewSemesters();
            }
            catch (Exception ex)
            {
                ShowFormError(EditSemesterFormError.ClientID, ex.Message);
            }
        }

        protected void ButtonCancelSemester_OnClick(object sender, EventArgs e)
        {
            HideEditSemesterForm();
        }
    }
}